﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using ViewMaker.Core.Utils;
using System.IO;
using System.Xml.Serialization;
using System.IO.IsolatedStorage;
using System.Windows.Media;
using System.Windows.Input;
using ViewMaker.Core.ViewModels;
using System.Diagnostics;
using System.ComponentModel.DataAnnotations;
using ViewMaker.Core.Controls;
using System.Windows.Markup;

namespace ViewMaker.Core
{
    [View(ViewControlType.Grid, Title = "ViewMaker Settings")]
    [ViewProperty(GridViewControl.Properties.ItemColumnSize, 4)]
    public class ViewMakerSettings : ViewModelBase, IEditableObject
    {
        private static readonly object lockObject = new object();
        private const string filename = "Settings.xml";
        public static ViewMakerSettings Instance 
        { 
            get 
            {
                if (_instance == null)
                {
                    lock (lockObject)
                    {
                        if (_instance == null)
                        {
                            CreateInstance();
                        }
                    }
                }
                return _instance; 
            } 
        }
        private static ViewMakerSettings _instance;

        private static void CreateInstance()
        {
#if !SILVERLIGHT
            if (File.Exists(filename))
            {
                try
                {
                    using (var st = new FileStream(filename, FileMode.Open, FileAccess.Read))
                    {
                        var ser = new XmlSerializer(typeof(ViewMakerSettings));
                        _instance = (ViewMakerSettings)ser.Deserialize(st);
                    }
                }
                catch (Exception ex)
                {
                    _instance = new ViewMakerSettings();
                    Debug.WriteLine(ex.ToString());
                }
            }
            else
            {
                _instance = new ViewMakerSettings();
            }
#else
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (store.FileExists(filename)) 
                {
                    try
                    {
                        using (var st = store.OpenFile(filename, FileMode.Open, FileAccess.Read))
                        {
                            var ser = new XmlSerializer(typeof(ViewMakerSettings));
                            _instance = (ViewMakerSettings)ser.Deserialize(st);
                        }
                    }
                    catch (Exception ex)
                    {
                        _instance = new ViewMakerSettings();
                        Debug.WriteLine(ex.ToString());
                    }
                }
                else
                {
                    _instance = new ViewMakerSettings();
                }
            }
#endif
        }

        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "LayoutOrientationList")]
        public LayoutOrientation DefaultRadioButtonOrientation { get; set; }

        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "LayoutHeaderPositionList")]
        public LayoutHeaderPosition DefaultPanelHeaderPosition { get; set; }

        public string DefaultPanelMargin { get; set; }
        public int? DefaultPanelItemWidth { get; set; }

        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "LayoutHorizontalAlignmentList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public LayoutHorizontalAlignment? DefaultGridHeaderHorizontalContentAlignment { get; set; }

        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "LayoutOrientationList")]
        public LayoutOrientation DefaultGridOrientation { get; set; }

        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "LayoutHeaderPositionList")]
        public LayoutHeaderPosition DefaultGridHeaderPosition { get; set; }

        public int? DefaultStackPanelHeaderWidth { get; set; }
        public int? DefaultStackPanelItemWidth { get; set; }

        public int? DefaultCanvasHeaderWidth { get; set; }
        public int? DefaultCanvasItemWidth { get; set; }

        public int CanvasVerticalOffset { get; set; }
        public int CanvasHorizontalOffset { get; set; }

        public int? DefaultDataGridWidth { get; set; }
        public int? DefaultDataGridHeight { get; set; }

        public string DefaultButtonItemMargin { get; set; }

        public double? DefaultWindowFontSize { get; set; }

        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ColorList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string DefaultWindowForeground { get; set; }

        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ColorList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string DefaultWindowBackground { get; set; }


        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "DefaultDetailPanelTypeList")]
        public ViewControlType DefaultDetailPanelType { get; set; }

        /// <summary>
        /// パインドするパス表示の際にシステム型をフィルターするか
        /// </summary>
        [Display(Name = "Enable Binding Path Filter")]
        public bool EnableBindingPathFilter { get; set; }

        public ViewMakerSettings()
        {
            this.DefaultRadioButtonOrientation = LayoutOrientation.Vertical;

            this.DefaultPanelHeaderPosition = LayoutHeaderPosition.Left;

            this.DefaultStackPanelHeaderWidth = 100;

            this.DefaultCanvasHeaderWidth = 100;
            this.CanvasVerticalOffset = 30;
            this.CanvasHorizontalOffset = 300;
            this.DefaultCanvasItemWidth = 200;

            this.DefaultGridHeaderHorizontalContentAlignment = LayoutHorizontalAlignment.Left;
            this.DefaultGridOrientation = LayoutOrientation.Horizontal;
            this.DefaultGridHeaderPosition = LayoutHeaderPosition.Flat;

            this.DefaultGridHeaderPosition = LayoutHeaderPosition.Flat;
            this.DefaultButtonItemMargin = "5";

            this.DefaultDetailPanelType = ViewControlType.StackPanel;

            this.EnableBindingPathFilter = true;
        }

        [Browsable(false)]
        [XmlIgnore]
        public string[] ColorList
        {
            get { return typeof(Colors).GetProperties().Select(x => x.Name).ToArray(); }
        }

        public List<string> LayoutVerticalAlignmentList { get { return TypeUtil.GetEnumNames(typeof(LayoutVerticalAlignment)); } }
        public List<string> LayoutOrientationList { get { return TypeUtil.GetEnumNames(typeof(LayoutOrientation)); } }
        public List<string> LayoutHeaderPositionList { get { return TypeUtil.GetEnumNames(typeof(LayoutHeaderPosition)); } }
        public List<string> LayoutHorizontalAlignmentList { get { return TypeUtil.GetEnumNames(typeof(LayoutHorizontalAlignment)); } }

        public ViewControlType[] DefaultDetailPanelTypeList { get { return new ViewControlType[] { ViewControlType.Grid, ViewControlType.StackPanel }; } }

        #region IEditableObject メンバー

        private ViewMakerSettings original;

        void IEditableObject.BeginEdit()
        {
            original = (ViewMakerSettings)this.MemberwiseClone();
        }

        void IEditableObject.CancelEdit()
        {
            foreach (var prop in typeof(ViewMakerSettings).GetProperties().Where(x => x.CanWrite))
            {
                prop.SetValue(this, prop.GetValue(original, null), null);
            }
        }

        void IEditableObject.EndEdit()
        {
#if !SILVERLIGHT
            using (var st = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                var ser = new XmlSerializer(typeof(ViewMakerSettings));
                ser.Serialize(st, this);
            }
#else
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var st = store.CreateFile(filename))
                {
                    var ser = new XmlSerializer(typeof(ViewMakerSettings));
                    ser.Serialize(st, this);
                }
            }
#endif
        }

        #endregion

    }
}
